-
Notifications
You must be signed in to change notification settings - Fork 93
DataJoint 2.0 #1311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
DataJoint 2.0 #1311
Conversation
Chore/dev env fixes
Impr/modernize pre commit
switch settings to use pydantic-settings
…tings-management-adsuG
- Remove ConfigWrapper class and backward compatibility layer - Use direct pydantic BaseSettings with typed nested models - Change context manager from config(...) to config.override(...) - Add validate_assignment=True for runtime type checking - Improve store spec validation with clear error messages - Update all tests to use new API - Preserve dict-style access via __getitem__/__setitem__ for convenience
Config file search: - Search for datajoint.json recursively up from cwd - Stop at .git/.hg boundaries or filesystem root - Warn if no config file found (instead of silently using defaults) Secrets management: - Add .secrets/ directory support (next to datajoint.json) - Support /run/secrets/datajoint/ for Docker/Kubernetes - Use SecretStr for password and aws_secret_access_key - Secrets masked in repr/logs, excluded from save() - Dict access automatically unwraps SecretStr for compatibility Breaking changes: - Config file renamed from dj_local_conf.json to datajoint.json - No more ~/.datajoint_config.json (project-only config) - Secrets should be in env vars or .secrets/ directory
Add convenient type aliases that map to MySQL types: - float32 -> float - float64 -> double - int32 -> int - uint32 -> int unsigned - int16 -> smallint - uint16 -> smallint unsigned - int8 -> tinyint - uint8 -> tinyint unsigned These aliases follow the same pattern as UUID, storing the original type in the column comment for round-tripping.
- int64 -> bigint - uint64 -> bigint unsigned
Add comprehensive tests for the new type aliases feature: - Pattern matching tests for all 10 type aliases - MySQL type mapping verification - Table creation with type aliases - Insert and fetch operations - Primary key usage with type aliases - Nullable column support
Credentials should be managed via environment variables or .secrets/ directory, not stored in config files.
Config files should be created/edited manually and version controlled, not generated programmatically.
- Rewrite settings.md with new config structure and secrets management - Update credentials.md to remove set_password and save methods - Update quick-start.md with new config file name and patterns - Add documentation for .secrets/ directory and environment variables
Document the new type aliases (float32, float64, int8-64, uint8-64) in the datatypes documentation with a table of mappings and example usage.
- Update pyproject.toml to require Python >=3.10 (was >=3.9) - Update ruff target-version to py310 - Update pixi Python version constraint - Modernize type hints to use Python 3.10+ union syntax (X | Y instead of Union[X, Y], X | None instead of Optional[X]) - Use built-in dict, list, tuple for generics instead of typing imports - Update MySQL documentation reference from 5.7 to 8.0
Documentation updates: - docs/src/client/install.md: Update Python requirement from 3.4+ to 3.10+ - docs/src/quick-start.md: Update Python requirement from 3.8+ to 3.10+ - docs/src/quick-start.md: Update MySQL doc link from 5.7 to 8.0 - docs/src/develop.md: Update Python requirement from 3.9+ to 3.10+ - docs/src/develop.md: Fix version.py path (datajoint/ -> src/datajoint/) Configuration updates: - docker-compose.yaml: Update default PY_VER from 3.9 to 3.10 - .github/workflows/test.yaml: Remove Python 3.9 and MySQL 5.7 from test matrix - .github/workflows/post_draft_release_published.yaml: Update to Python 3.10 - .github/workflows/post_draft_release_published.yaml: Fix version.py path
…' into claude/add-type-aliases-6uN3E
Draft specification document for the new `file@store` column type that stores files with JSON metadata. Includes syntax, storage format, insert/fetch behavior, and comparison with existing attachment types.
- Single storage backend per pipeline (no @store suffix) - Use fsspec for multi-backend support (local, S3, GCS, Azure) - Configuration via datajoint.toml at project level - Configurable partition patterns based on primary key attributes - Hierarchical project structure with tables/ and objects/ dirs
- Use datajoint.json instead of datajoint.toml - Add ObjectStorageSettings class spec for settings.py - Support DJ_OBJECT_STORAGE_* environment variables - Support .secrets/ directory for credentials - Partition pattern is per-pipeline (one per settings file) - No deduplication - each record owns its file
- Random hash suffix for filenames (URL-safe, filename-safe base64) - Configurable hash_length setting (default: 8, range: 4-16) - Upload-first transaction strategy with cleanup on failure - Batch insert atomicity handling - Orphaned file detection/cleanup utilities (future)
Key changes: - Support both files and folders - Immutability contract: insert, read, delete only - Deterministic bidirectional path mapping from schema/table/field/PK - Copy-first insert: copy fails → no DB insert attempted - DB-first delete: file delete is best-effort (stale files acceptable) - Fetch returns handle (FileRef), no automatic download - JSON metadata includes is_folder, file_count for folders - FileRef class with folder operations (listdir, walk)
…orage Major changes to hash-addressed storage model: - Rename content_registry.py → hash_registry.py for clarity - Always store full path in metadata (protects against config changes) - Use stored path directly for retrieval (no path regeneration) - Add delete_path() as primary function, deprecate delete_hash() - Add get_size() as primary function, deprecate get_hash_size() - Update gc.py to work with paths instead of hashes - Update builtin_codecs.py HashCodec to use new API This design enables seamless migration from v0.14: - Legacy data keeps old paths in metadata - New data uses new path structure - GC compares stored paths against filesystem Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove uuid_from_buffer from hash.py (dead code) - connection.py now uses hashlib.md5().hexdigest() directly - Update test_hash.py to test key_hash instead Co-Authored-By: Claude Opus 4.5 <[email protected]>
Remove dead code that was only tested but never used in production: - hash_exists (gc uses set operations on paths) - delete_hash (gc uses delete_path directly) - get_size (gc collects sizes during walk) - get_hash_size (wrapper for get_size) Remaining API: compute_hash, build_hash_path, get_store_backend, get_store_subfolding, put_hash, get_hash, delete_path Co-Authored-By: Claude Opus 4.5 <[email protected]>
feat: Add NpyCodec for lazy-loading numpy arrays
src/datajoint/__init__.py
Outdated
| "errors", | ||
| "migrate", | ||
| "DataJointError", | ||
| "key", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dimitri-yatsenko The datajoint-docs state that dj.key is removed in 2.0 (see https://github.com/datajoint/datajoint-docs/blob/pre/v2.0/src/reference/specs/fetch-api.md#removed-methods-and-parameters), but' key' is still listed in __all__ in here. Should key be removed from the exports here, or does the documentation need to be updated?
|
The PR description states "Removed
This behavior is correctly documented in datajoint-docs, but the PR description could be updated to: "Renamed method parameter |
|
There's a TODO at |
| ] | ||
| else: # positional | ||
| warnings.warn( | ||
| "Positional inserts (tuples/lists) are deprecated and will be removed in a future version. " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This deprecation isn't documented in the migration guide. Should it be added, or is this intentionally a soft deprecation for now?
src/datajoint/diagram.py
Outdated
|
|
||
| See Also | ||
| -------- | ||
| https://docs.datajoint.com/core/datajoint-python/0.14/client/install/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated URL (0.14 docs). Consider updating to https://docs.datajoint.com/how-to/read-diagrams/ or adding Diagram dependencies to the installation guide.
src/datajoint/heading.py
Outdated
| if original_type.startswith("external"): | ||
| raise DataJointError( | ||
| f"Legacy datatype `{original_type}`. Migrate your external stores to datajoint 0.12: " | ||
| "https://docs.datajoint.io/python/admin/5-blob-config.html#migration-between-datajoint-v0-11-and-v0-12" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Outdated URL and message. This error triggers for legacy :external: format, but points to 0.11→0.12 migration on old datajoint.io domain. Should reference Phase 6 of the 2.0 migration guide: https://docs.datajoint.com/how-to/migrate-from-0x/#phase-6-external-storage-database
src/datajoint/expression.py
Outdated
|
|
||
| For single-row fetch, use fetch1() which is unchanged. | ||
|
|
||
| See migration guide: https://docs.datajoint.com/migration/fetch-api |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broken URL - /migration/fetch-api doesn't exist. Should be: https://docs.datajoint.com/reference/specs/fetch-api/
Add migrate_columns() and supporting functions for Phase 2 of the 0.14.6 → 2.0 migration: - analyze_columns(): Identify columns needing type labels - migrate_columns(): Add core type markers to column comments - NATIVE_TO_CORE_TYPE mapping for type conversion - Support for bool/datetime special cases - Dry-run mode for previewing changes Also adds placeholder stubs for Phase 3-4 migration functions: - migrate_external(): For external storage migration - migrate_filepath(): For filepath attribute migration - finalize_migration(): For Phase 4 finalization These functions implement the migration guide documented in datajoint-docs/src/how-to/migrate-from-0x.md. Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
diagram.py:26,33 — Lines 26 and 33 use bare |
|
Suggestion: blob.py:162,366 — These if len(blob) != blob_size:
raise DataJointError("Blob size mismatch") |
|
There are a few |
The tests test_sigint, test_sigterm, test_suppress_dj_errors, and test_populate_exclude_error_and_ignore_jobs were flaky due to a race condition: jobs created with scheduled_time=NOW(3) might not pass the scheduled_time <= NOW(3) check if checked in the same millisecond. Fix by using delay=-1 in auto-refresh during populate(), ensuring jobs are scheduled 1 second in the past and immediately schedulable. Also update test_populate_exclude_error_and_ignore_jobs to use delay=-1 in its explicit refresh() call. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Replace bare except: with except ImportError: in diagram.py - Replace assert statements with explicit raises in blob.py - Replace assert False with explicit raises in expression.py and declare.py - Implement hash verification in objectref.py Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
@MilagrosMarin Thank you for the thorough review! All feedback has been addressed in PR #1332:
See commit 334da76 for the changes. |
dj.key was removed in 2.0 but was still listed in __all__ without being imported or defined. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove `schema` alias for `Schema` (use `dj.Schema` instead of `dj.schema`) - Remove `Di` alias for `Diagram` (use `dj.Diagram` or `dj.ERD`) - Update all examples, tests, and docstrings Co-Authored-By: Claude Opus 4.5 <[email protected]>
Update outdated docs.datajoint.com URLs to new paths: - diagram.py: /how-to/installation/ - heading.py: /how-to/migrate-from-0x/ - expression.py: /how-to/migrate-from-0x/ Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove key_hash function (legacy job table debugging) - Remove hash.py module - Fix test_erd.py to use dj.Diagram instead of dj.Di - Bump version to 2.0.0a20 Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Remove ERD alias (use dj.Diagram) - Rename test_erd_algebra to test_diagram_algebra - Remove test_diagram_aliases test - Bump version to 2.0.0a21 Co-Authored-By: Claude Opus 4.5 <[email protected]>
* feat: add Phase 2 migration functions for column type and blob markers Add migrate_columns() and supporting functions for Phase 2 of the 0.14.6 → 2.0 migration: - analyze_columns(): Identify columns needing type labels - migrate_columns(): Add core type markers to column comments - NATIVE_TO_CORE_TYPE mapping for type conversion - Support for bool/datetime special cases - Dry-run mode for previewing changes Also adds placeholder stubs for Phase 3-4 migration functions: - migrate_external(): For external storage migration - migrate_filepath(): For filepath attribute migration - finalize_migration(): For Phase 4 finalization These functions implement the migration guide documented in datajoint-docs/src/how-to/migrate-from-0x.md. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: resolve flaky tests by using delay=-1 for immediate job scheduling The tests test_sigint, test_sigterm, test_suppress_dj_errors, and test_populate_exclude_error_and_ignore_jobs were flaky due to a race condition: jobs created with scheduled_time=NOW(3) might not pass the scheduled_time <= NOW(3) check if checked in the same millisecond. Fix by using delay=-1 in auto-refresh during populate(), ensuring jobs are scheduled 1 second in the past and immediately schedulable. Also update test_populate_exclude_error_and_ignore_jobs to use delay=-1 in its explicit refresh() call. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: address PR #1311 review comments - Replace bare except: with except ImportError: in diagram.py - Replace assert statements with explicit raises in blob.py - Replace assert False with explicit raises in expression.py and declare.py - Implement hash verification in objectref.py Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: remove deprecated dj.key from __all__ dj.key was removed in 2.0 but was still listed in __all__ without being imported or defined. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: remove deprecated dj.schema and dj.Di aliases - Remove `schema` alias for `Schema` (use `dj.Schema` instead of `dj.schema`) - Remove `Di` alias for `Diagram` (use `dj.Diagram` or `dj.ERD`) - Update all examples, tests, and docstrings Co-Authored-By: Claude Opus 4.5 <[email protected]> * docs: fix broken documentation links Update outdated docs.datajoint.com URLs to new paths: - diagram.py: /how-to/installation/ - heading.py: /how-to/migrate-from-0x/ - expression.py: /how-to/migrate-from-0x/ Co-Authored-By: Claude Opus 4.5 <[email protected]> * chore: bump version to 2.0.0a19 Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: remove deprecated dj.key_hash and dj.Di - Remove key_hash function (legacy job table debugging) - Remove hash.py module - Fix test_erd.py to use dj.Diagram instead of dj.Di - Bump version to 2.0.0a20 Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: remove deprecated dj.ERD alias - Remove ERD alias (use dj.Diagram) - Rename test_erd_algebra to test_diagram_algebra - Remove test_diagram_aliases test - Bump version to 2.0.0a21 Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]>
The 0.14.6 implementation used: - Table definitions: blob@store, attach@store, filepath@store - Column comments: :blob@store:, :attach@store:, :filepath@store: The migrate.py patterns incorrectly searched for :external-store: format. Corrected to match actual v0.14.6 column comment format. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Changes: - Added prominent migration guide callout near top of README - Updated Resources section with new docs structure URLs: - Tutorials: docs.datajoint.com/tutorials/ - How-To Guides: docs.datajoint.com/how-to/ - API Reference: docs.datajoint.com/reference/api/ - Migration Guide: docs.datajoint.com/how-to/migrate-from-0x/ - Organized Resources section with better formatting Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Summary
DataJoint 2.0 is a major release that modernizes the entire codebase while maintaining backward compatibility for core functionality. This release focuses on extensibility, type safety, and developer experience.
Planning: DataJoint 2.0 Plan | Milestone 2.0
Major Features
Codec System (Extensible Types)
Replaces the adapter system with a modern, composable codec architecture:
<blob>,<json>,<attach>,<filepath>,<object>,<hash>,<npy><blob>wraps<json>for external storage)__init_subclass__validate()method for type checking before insertSemantic Matching
Attribute lineage tracking ensures joins only match semantically compatible attributes:
idornamesemantic_check=Falsefor legacy permissive behaviorPrimary Key Rules
Rigorous primary key propagation through all operators:
dj.U('attr')creates ad-hoc grouping entitiesAutoPopulate 2.0 (Jobs System)
Per-table job management with enhanced tracking:
~~_job_timestampand~~_job_durationcolumns~~table_namejob tabletable.progress()returns (remaining, total)Modern Fetch & Insert API
New fetch methods:
to_dicts()- List of dictionariesto_pandas()- DataFrame with PK as indexto_arrays(*attrs)- NumPy arrays (structured or individual)keys()- Primary keys onlyfetch1()- Single rowInsert improvements:
validate()- Check rows before insertingchunk_size- Batch large insertsinsert_dataframe()- DataFrame with index handlingType Aliases
Core DataJoint types for portability:
int8,int16,int32,int64uint8,uint16,uint32,uint64float32,float64booluuidObject Storage
Content-addressed and object storage types:
<hash>- Content-addressed storage with deduplication<object>- Named object storage (Zarr, folders)<npy>- NumPy arrays as .npy files<filepath>- Reference to managed files<attach>- File attachments (uploaded on insert)Virtual Schema Infrastructure (#1307)
New schema introspection API for exploring existing databases:
Schema.get_table(name)- Direct table access with auto tier prefix detectionSchema['TableName']- Bracket notation accessfor table in schema- Iterate tables in dependency order'TableName' in schema- Check table existencedj.virtual_schema()- Clean entry point for accessing schemasdj.VirtualModule()- Virtual modules with custom namesCLI Improvements
The
djcommand-line interface for interactive exploration:dj -s schema:alias- Load schemas as virtual modules--host,--user,--password- Connection options-hconflict with--helpSettings Modernization
Pydantic-based configuration with validation:
dj.config.override()context manager.secrets/)DJ_HOST, etc.)Migration Utilities
Helper functions for migrating from 0.14.x to 2.0:
analyze_blob_columns()- Identify columns needing type markersmigrate_blob_columns()- Add:<blob>:prefixes to column commentscheck_migration_status()- Verify migration readinessadd_job_metadata_columns()- Add hidden job tracking columnsLicense Change
Changed from LGPL to Apache 2.0 license (#1235 (discussion)):
Breaking Changes
Removed Support
fetch()with format parametercreate_virtual_module(usedj.virtual_schema()ordj.VirtualModule())~logtable (IMPR: Deprecate and Remove the~logTable. #1298)Removed API Components
dj.key- Usetable.keys()insteaddj.key_hash()- Removed (was for legacy job debugging)dj.schema()- Usedj.Schema()(capitalized)dj.ERD()- Usedj.Diagram()dj.Di()- Usedj.Diagram()API Changes
fetch()→to_dicts(),to_pandas(),to_arrays()fetch(format='frame')→to_pandas()fetch(as_dict=True)→to_dicts()safemode→prompt(theconfig['safemode']setting remains and controls the default behavior)Semantic Changes
Documentation
Developer Documentation (this repo)
Comprehensive updates in
docs/:User Documentation (datajoint-docs)
Full documentation site following the Diátaxis framework:
Tutorials (learning-oriented, Jupyter notebooks):
How-To Guides (task-oriented):
Reference (specifications):
Project Structure
src/layout for proper packaging (IMPR:srclayout #1267)Test Plan
Closes
Milestone 2.0 Issues
~logTable. #1298 - Deprecate and remove~logtablesuper.deletekwargs toPart.delete#1276 - Part.delete kwargs pass-throughsrclayout #1267 -srclayoutdj.Toporders the preview withorder_by#1242 -dj.Toporders the preview withorder_byBug Fixes
pyarrow(apandasdependency) #1202 - DataJoint import error with missing pyarrowValueErrorin DataJoint-Python 0.14.3 when using numpy 2.2.* #1201 - ValueError with numpy 2.2dj.Diagram()and new release ofpydot==3.0.*#1169 - Error with dj.Diagram() and pydot 3.0Improvements
Related PRs
Migration Guide
See How to Migrate from 1.x for detailed migration instructions.
🤖 Generated with Claude Code